package com.ultrapower.util.topology;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ultrapower.bean.ApplicationBean;

public class AgentHistogramList {

	    // stores times series data per agent
	    private final Map<ApplicationBean, AgentHistogram> agentHistogramMap = new HashMap<>();

	    public AgentHistogramList() {
	    }

	    public AgentHistogramList(ApplicationBean application, List<ResponseTime> responseHistogramList) {
	        if (responseHistogramList == null) {
	            throw new NullPointerException("responseHistogramList must not be null");
	        }

	        for (ResponseTime responseTime : responseHistogramList) {
	            for (Map.Entry<String, TimeHistogram> agentEntry : responseTime.getAgentHistogram()) {
	                TimeHistogram timeHistogram = agentEntry.getValue();
	                this.addAgentHistogram(agentEntry.getKey(), application.getServiceTypeCode(), timeHistogram);
	            }
	        }
	    }


	    public void addTimeHistogram(ApplicationBean agentId, Collection<TimeHistogram> histogramList) {
	        if (agentId == null) {
	            throw new NullPointerException("agentId must not be null");
	        }
	        if (histogramList == null) {
	            throw new NullPointerException("histogramList must not be null");
	        }
	        AgentHistogram agentHistogram = getAgentHistogram(agentId);
	        agentHistogram.addTimeHistogram(histogramList);
	    }

	    public void addTimeHistogram(ApplicationBean agentId, TimeHistogram timeHistogram) {
	        if (agentId == null) {
	            throw new NullPointerException("agentId must not be null");
	        }
	        if (timeHistogram == null) {
	            throw new NullPointerException("timeHistogram must not be null");
	        }
	        AgentHistogram agentHistogram = getAgentHistogram(agentId);
	        agentHistogram.addTimeHistogram(timeHistogram);
	    }

	    public void addAgentHistogram(String agentName, short serviceType, Collection<TimeHistogram> histogramList) {
	        ApplicationBean agentId = new ApplicationBean(agentName, serviceType);
	        addTimeHistogram(agentId, histogramList);
	    }

	    public void addAgentHistogram(String agentName, short serviceType, TimeHistogram timeHistogram) {
	        ApplicationBean agentId = new ApplicationBean(agentName, serviceType);
	        addTimeHistogram(agentId, timeHistogram);
	    }



	    private AgentHistogram getAgentHistogram(ApplicationBean agentId) {
	        if (agentId == null) {
	            throw new NullPointerException("agentId must not be null");
	        }

	        AgentHistogram agentHistogram = agentHistogramMap.computeIfAbsent(agentId, k -> new AgentHistogram(agentId));
	        return agentHistogram;
	    }

	    public Histogram mergeHistogram(short serviceType) {
	        final Histogram histogram = new Histogram(serviceType);
	        for (AgentHistogram agentHistogram : getAgentHistogramList()) {
	            histogram.add(agentHistogram.getHistogram());
	        }
	        return histogram;
	    }



	    public void addAgentHistogram(AgentHistogram agentHistogram) {
	        if (agentHistogram == null) {
	            throw new NullPointerException("agentHistogram must not be null");
	        }
	        final String hostName = agentHistogram.getId();
	        short serviceType = agentHistogram.getServiceType();

	        ApplicationBean agentId = new ApplicationBean(hostName, serviceType);
	        AgentHistogram findAgentHistogram = getAgentHistogram(agentId);
	        findAgentHistogram.addTimeHistogram(agentHistogram.getTimeHistogram());
	    }

	    public void addAgentHistogram(AgentHistogramList addAgentHistogramList) {
	        if (addAgentHistogramList == null) {
	            throw new NullPointerException("agentHistogram must not be null");
	        }
	        for (AgentHistogram agentHistogram : addAgentHistogramList.agentHistogramMap.values()) {
	            addAgentHistogram(agentHistogram);
	        }
	    }

	    public Collection<AgentHistogram> getAgentHistogramList() {
	        return agentHistogramMap.values();
	    }

	    @Override
	    public String toString() {
	        return "AgentHistogramList{"
	                    + agentHistogramMap +
	                '}';
	    }

	    public int size() {
	        return this.agentHistogramMap.size();
	    }
}
